//

#import "SimImageEditorVC.h"
#import "CLClippingTool.h"
#import "CLRotateTool.h"
#import "UIButton+SimAdditions.h"
#import "CLImageTools.h"
#import <GPUImage/GPUImage.h>
#import "UIImage+SimAdditions.h"
#import "UIBarButtonItem+SimAdditions.h"
#import "SimImageEditModel.h"
#import "SimAlertView.h"
#import "UIView+SimAdditions.h"
#import "UIViewController+SimAddition.h"
#import "SimLoading.h"

#define kContentEdgeGap 5.0f


@interface SimImageEditorVC () <UIScrollViewDelegate, UIBarPositioningDelegate>


@property (nonatomic, strong) UIScrollView *scrollView;
@property (nonatomic, strong) UIImageView  *imageView;
@property (nonatomic, strong) UIView    *menuView;
@property (nonatomic, strong) CLImageToolBase *currentTool;

@property (nonatomic, strong) SimImageEditModel *editModel;

@end

@implementation SimImageEditorVC
{
}


- (id)initWithEditModel:(SimImageEditModel *)editModel
{
    self = [self init];
    if (self){
        _editModel = editModel;
    }
    return self;
}

- (void)dealloc
{
    NSLog(@"dealloc");
}

- (void)viewDidLoad
{
    [super viewDidLoad];
    if (self.title.length == 0) {
        self.title = @"编辑";
    }
    self.view.backgroundColor = [UIColor whiteColor];
    
    if([self respondsToSelector:@selector(automaticallyAdjustsScrollViewInsets)]){
        self.automaticallyAdjustsScrollViewInsets = NO;
    }
    if([self.navigationController respondsToSelector:@selector(interactivePopGestureRecognizer)]){
        self.navigationController.interactivePopGestureRecognizer.enabled = NO;
    }
    _scrollView = [[UIScrollView alloc] initWithFrame:CGRectMake(0, kContentEdgeGap, self.view.width, self.view.height-kBotttomMenuHeight-2*kContentEdgeGap)];
    _scrollView.backgroundColor = [UIColor clearColor];
    _scrollView.delegate = self;
    [self.view addSubview:_scrollView];
    
    _imageView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, self.view.width, 10)];
    _imageView.center = CGPointMake(_scrollView.width/2, _scrollView.height/2);
    _imageView.image = _editModel.processImage;
    [self.view addSubview:_scrollView];
    [_scrollView addSubview:_imageView];
    
    _menuView = [[UIView alloc] initWithFrame:CGRectMake(0, _scrollView.bottom+kContentEdgeGap, self.view.width, kBotttomMenuHeight)];
    _menuView.backgroundColor = HEXRGBCOLOR(0x373737);
    [self setupMenuViews];
    [self.view addSubview:_menuView];
    
    [self updateNavBarItemWithEditting:NO];
    [self updateMenuPositionWithEditting:NO];

    [self restoreImageView];
    [self updateEffectBtnStatus];
    
}

- (void)viewWillLayoutSubviews
{
    [super viewWillLayoutSubviews];
    _scrollView.height = self.view.height-kBotttomMenuHeight-2*kContentEdgeGap;
    _menuView.top = _scrollView.bottom+kContentEdgeGap;
}

- (void)setupMenuViews
{
    UILabel *line = [[UILabel alloc] initWithFrame:CGRectMake(self.view.width/2-1, 3, 1, kBotttomMenuHeight-6)];
    line.backgroundColor = HEXRGBCOLOR(0x707070);
    [_menuView addSubview:line];
    
    CGFloat btnGap = self.view.width/16;
    CGFloat btnWidth = ((self.view.width/2) - btnGap*2)/2;
    
        for (NSInteger i=0; i<4; i++) {
        UIButton *menuBtn = [[UIButton alloc] init];
        menuBtn.backgroundColor = [UIColor clearColor];
        menuBtn.titleLabel.font = [UIFont systemFontOfSize:10];
        [menuBtn setTitleEdgeInsets:UIEdgeInsetsMake(34, -44, 0, -23)];
        menuBtn.titleLabel.backgroundColor = [UIColor clearColor];
        menuBtn.titleLabel.textAlignment = NSTextAlignmentCenter;
        menuBtn.titleLabel.contentMode = UIViewContentModeCenter;
        [menuBtn setImageEdgeInsets:UIEdgeInsetsMake(-8, 0, 0, -22)];
        [menuBtn setTitleColor:HEXRGBCOLOR(0x64dcdc) forState:UIControlStateHighlighted];
        [menuBtn setTitleColor:HEXRGBCOLOR(0xffffff) forState:UIControlStateNormal];
        [menuBtn setTitleColor:HEXRGBCOLOR(0x64dcdc) forState:UIControlStateSelected];
        if (i== 0) {
            menuBtn.frame = CGRectMake(btnGap, 0, btnWidth, _menuView.height);
            [menuBtn setImage:[UIImage imageNamed:@"icon_original_normal"] forState:UIControlStateNormal];
            [menuBtn setImage:[UIImage imageNamed:@"icon_original_selected"] forState:UIControlStateSelected];
            [menuBtn setImage:SimUIImageNamed(@"icon_original_selected") forState:UIControlStateHighlighted];
            [menuBtn setImage:SimUIImageNamed(@"icon_original_normal") forState:UIControlStateSelected|UIControlStateHighlighted];
            [menuBtn setTitle:@"原图" forState:UIControlStateNormal];
        }else if (i == 1){
            menuBtn.frame = CGRectMake(btnGap+btnWidth, 0, btnWidth, _menuView.height);
            [menuBtn setImage:[UIImage imageNamed:@"icon_adjustment_normal"] forState:UIControlStateNormal];
            [menuBtn setImage:[UIImage imageNamed:@"icon_adjustment_selected"] forState:UIControlStateHighlighted];
            [menuBtn setImage:SimUIImageNamed(@"icon_adjustment_selected") forState:UIControlStateSelected];
            [menuBtn setImage:SimUIImageNamed(@"icon_adjustment_normal") forState:UIControlStateSelected|UIControlStateHighlighted];
            [menuBtn setTitle:@"增强" forState:UIControlStateNormal];
        }else if (i == 2){
            menuBtn.frame = CGRectMake(self.view.width/2+btnGap, 0, btnWidth, _menuView.height);
            [menuBtn setImage:[UIImage imageNamed:@"icon_crop"] forState:UIControlStateNormal];
            [menuBtn setImage:[UIImage imageNamed:@"icon_crop_highlighted"] forState:UIControlStateHighlighted];
            [menuBtn setTitle:@"裁剪" forState:UIControlStateNormal];
        }else if (i == 3){
            menuBtn.frame = CGRectMake(self.view.width/2+btnGap+btnWidth, 0, btnWidth, _menuView.height);
            [menuBtn setImage:[UIImage imageNamed:@"icon_rotate"] forState:UIControlStateNormal];
            [menuBtn setImage:[UIImage imageNamed:@"icon_rotate_highlighted"] forState:UIControlStateHighlighted];
            [menuBtn setTitle:@"旋转" forState:UIControlStateNormal];
        }
        menuBtn.tag = i+10;
        [menuBtn addTarget:self action:@selector(clickMenuBtn:) forControlEvents:UIControlEventTouchUpInside];
        [_menuView addSubview:menuBtn];
    }
    
    
    [self updateEffectBtnStatus];
}

#pragma mark - Action
- (void)clickMenuBtn:(UIButton *)btn
{
    switch (btn.tag - 10) {
        case 0:
            _editModel.editType = IET_Origin;
            _imageView.image = _editModel.orignalImage;
            _editModel.processImage = _imageView.image;
            [self resetImageViewFrame];
            [self resetZoomScaleWithAnimate:YES];
            [self updateEffectBtnStatus];
            break;
        case 1:
            btn.userInteractionEnabled = NO;
            _editModel.editType |= IET_Enhance;
            [self doEnhance];
            [self updateEffectBtnStatus];
            break;
        case 2:
            [self beginToolWithClass:[CLClippingTool class]];
            break;
        case 3:
            [self beginToolWithClass:[CLRotateTool class]];
            break;
        default:
            break;
    }
}

- (void)doEnhance
{
    [SimLoading showOverlayLoadingInView:self.view];
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.001 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
        _imageView.image = [self processUsingGPUImage:_imageView.image];
        _editModel.processImage = _imageView.image;
        [SimLoading dismissInView:self.view];
    });
}

- (void)beginToolWithClass:(Class)toolClass
{
    if(self.currentTool){
        return;
    }
    
    if(toolClass){
        id instance = [toolClass alloc];
        if(instance!=nil && [instance isKindOfClass:[CLImageToolBase class]]){
            instance = [instance initWithImageEditor:self];
            self.currentTool = instance;
        }
    }
}

- (void)setCurrentTool:(CLImageToolBase *)currentTool
{
    if(currentTool != _currentTool){
        [_currentTool cleanup];
        _currentTool = currentTool;
        [_currentTool setup];
        
        BOOL editting = (_currentTool != nil);
        [self updateMenuPositionWithEditting:editting];
        [self updateNavBarItemWithEditting:editting];
    }
}

#pragma mark - Common
- (void)updateEffectBtnStatus
{
    UIButton *orignalBtn = (UIButton *)[self.menuView viewWithTag:10];
    UIButton *enhanceBtn = (UIButton *)[self.menuView viewWithTag:10+1];
    
    orignalBtn.selected = _editModel.editType == IET_Origin;
    enhanceBtn.selected = (IET_Enhance & _editModel.editType);
    
    orignalBtn.userInteractionEnabled = !orignalBtn.selected;
    enhanceBtn.userInteractionEnabled = !enhanceBtn.selected;
}

- (void)resetImageViewFrame
{
    dispatch_async(dispatch_get_main_queue(), ^{
        CGRect rct = _imageView.frame;
        rct.size = CGSizeMake(_scrollView.zoomScale*_imageView.image.size.width, _scrollView.zoomScale*_imageView.image.size.height);
        _imageView.frame = rct;
    });
}

- (void)resetZoomScaleWithAnimate:(BOOL)animated
{
    dispatch_async(dispatch_get_main_queue(), ^{
        CGFloat Rw = _scrollView.frame.size.width/_imageView.image.size.width;
        CGFloat Rh = _scrollView.frame.size.height/_imageView.image.size.height;
        CGFloat ratio = MIN(Rw, Rh);
        
        _scrollView.contentSize = _imageView.frame.size;
        _scrollView.minimumZoomScale = ratio;
        _scrollView.maximumZoomScale = MAX(ratio/240, 1/ratio);
        
        [_scrollView setZoomScale:_scrollView.minimumZoomScale animated:animated];
    });
}

- (void)restoreImageView
{
    dispatch_async(dispatch_get_main_queue(), ^{
        _imageView.image = _editModel.processImage;
        [self resetImageViewFrame];
        [self resetZoomScaleWithAnimate:NO];
    });
}

- (UIBarPosition)positionForBar:(id <UIBarPositioning>)bar
{
    return UIBarPositionTopAttached;
}

- (BOOL)shouldAutorotate
{
    return NO;
}

- (UIInterfaceOrientationMask)supportedInterfaceOrientations
{
    return UIInterfaceOrientationMaskPortrait;
}

#pragma mark- Menu && NavigationBar
- (void)updateMenuPositionWithEditting:(BOOL)editting
{
    [UIView animateWithDuration:kCLImageToolAnimationDuration
                     animations:^{
                         if(editting){
                             _menuView.top = self.view.height;
                         }
                         else{
                             _menuView.bottom = self.view.height;
                         }
                     }
     ];
}

- (void)updateNavBarItemWithEditting:(BOOL)editting
{
    
    UIBarButtonItem *leftItem = nil;
    UIBarButtonItem *rightItem = nil;
    if(editting){
        leftItem = [UIBarButtonItem itemWithText:@"取消" target:self action:@selector(cancelEditVC)];
        rightItem = [UIBarButtonItem itemWithText:@"应用" target:self action:@selector(applyEditStatus)];
    }
    else{
        leftItem = [UIBarButtonItem itemWithText:@"取消" target:self action:@selector(cancelEditVC)];
        rightItem = [UIBarButtonItem itemWithText:@"完成" target:self action:@selector(finishEditVC)];
    }
    self.navigationItem.leftBarButtonItem = leftItem;
    self.navigationItem.rightBarButtonItem = rightItem;
}

- (void)cancelEditStatus
{
    [self restoreImageView];
    self.currentTool = nil;
}

- (void)applyEditStatus
{
    self.view.userInteractionEnabled = NO;
    [self.currentTool executeWithCompletionBlock:^(UIImage *image, NSError *error, NSDictionary *userInfo) {
        if(error){
            SimAlertView *alert = [[SimAlertView alloc] initWithTitle:@"错误" message:error.localizedDescription btns:@[@"确认" ] dismissBlock:nil];
            [alert show];
        }
        else if(image){
            _editModel.editType |= IET_Edit;
            _editModel.processImage = image;
            _imageView.image = image;
            [self resetImageViewFrame];
        }
        self.currentTool = nil;
        self.view.userInteractionEnabled = YES;
    }];
}


- (void)cancelEditVC
{
    [self quitEditVC:NO];
}

- (void)finishEditVC
{
    [self quitEditVC:YES];
}

- (void)quitEditVC:(BOOL)hasChanged
{
    if (self.finishEdit) {
        self.finishEdit(self, hasChanged);
        self.finishEdit = nil;
    }
    
    if (self.navigationController.viewControllers.count > 1) {
        [self doPopBack];
    }else{
        [self dismissViewControllerAnimated:YES completion:nil];
    }
}

#pragma mark- ScrollView delegate
- (UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView
{
    return _imageView;
}

- (void)scrollViewDidZoom:(UIScrollView *)scrollView
{
    CGFloat Ws = _scrollView.frame.size.width;
    CGFloat Hs = _scrollView.frame.size.height - _scrollView.contentInset.top - _scrollView.contentInset.bottom;
    CGFloat W = _imageView.image.size.width*_scrollView.zoomScale;
    CGFloat H = _imageView.image.size.height*_scrollView.zoomScale;
    
    CGRect rct = _imageView.frame;
    rct.origin.x = MAX((Ws-W)/2, 0);
    rct.origin.y = MAX((Hs-H)/2, 0);
    _imageView.frame = rct;
}

#pragma mark - GPU Image

- (CIImage *)filteredImageUsingEnhanceFilterOnImage:(CIImage *)image
{
    return [CIFilter filterWithName:@"CIColorControls" keysAndValues:kCIInputImageKey, image, @"inputBrightness", [NSNumber numberWithFloat:0.0], @"inputContrast", [NSNumber numberWithFloat:1.14], @"inputSaturation", [NSNumber numberWithFloat:0.0], nil].outputImage;
}

- (CIRectangleFeature *)biggestRectangleInRectangles:(NSArray *)rectangles
{
    if (![rectangles count]) return nil;
    
    float halfPerimiterValue = 0;
    
    CIRectangleFeature *biggestRectangle = [rectangles firstObject];
    
    for (CIRectangleFeature *rect in rectangles)
    {
        CGPoint p1 = rect.topLeft;
        CGPoint p2 = rect.topRight;
        CGFloat width = hypotf(p1.x - p2.x, p1.y - p2.y);
        
        CGPoint p3 = rect.topLeft;
        CGPoint p4 = rect.bottomLeft;
        CGFloat height = hypotf(p3.x - p4.x, p3.y - p4.y);
        
        CGFloat currentHalfPerimiterValue = height + width;
        
        if (halfPerimiterValue < currentHalfPerimiterValue)
        {
            halfPerimiterValue = currentHalfPerimiterValue;
            biggestRectangle = rect;
        }
    }
    
    return biggestRectangle;
}

- (CIDetector *)highAccuracyRectangleDetector
{
    static CIDetector *detector = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^
                  {
                      detector = [CIDetector detectorOfType:CIDetectorTypeRectangle context:nil options:@{CIDetectorAccuracy : CIDetectorAccuracyHigh}];
                  });
    return detector;
}

- (CIImage *)correctPerspectiveForImage:(CIImage *)image withFeatures:(CIRectangleFeature *)rectangleFeature
{
    NSMutableDictionary *rectangleCoordinates = [NSMutableDictionary new];
    rectangleCoordinates[@"inputTopLeft"] = [CIVector vectorWithCGPoint:rectangleFeature.topLeft];
    rectangleCoordinates[@"inputTopRight"] = [CIVector vectorWithCGPoint:rectangleFeature.topRight];
    rectangleCoordinates[@"inputBottomLeft"] = [CIVector vectorWithCGPoint:rectangleFeature.bottomLeft];
    rectangleCoordinates[@"inputBottomRight"] = [CIVector vectorWithCGPoint:rectangleFeature.bottomRight];
    return [image imageByApplyingFilter:@"CIPerspectiveCorrection" withInputParameters:rectangleCoordinates];
}

- (UIImage *)processUsingGPUImage:(UIImage *)inputImage
{
    @autoreleasepool {
/*        CIImage *inputCIImage = [[CIImage alloc] initWithImage:inputImage];
        inputCIImage = [self filteredImageUsingEnhanceFilterOnImage:inputCIImage];
        CIRectangleFeature *rectangleFeature = [self biggestRectangleInRectangles:[[self highAccuracyRectangleDetector] featuresInImage:inputCIImage]];
        if (rectangleFeature){
            inputCIImage = [self correctPerspectiveForImage:inputCIImage withFeatures:rectangleFeature];
        }
        UIGraphicsBeginImageContext(CGSizeMake(inputCIImage.extent.size.height, inputCIImage.extent.size.width));
 
        UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
        UIGraphicsEndImageContext();
        _imageView.image = [UIImage imageWithCIImage:inputCIImage];
 */

        
        CIImage *inputCIImage = [[CIImage alloc] initWithImage:inputImage];
        
        CGAffineTransform transform = CGAffineTransformIdentity;
        CIFilter *clampFilter = [CIFilter filterWithName:@"CIAffineClamp"];
        [clampFilter setValue:inputCIImage forKeyPath:kCIInputImageKey];
        [clampFilter setValue:[NSValue valueWithBytes:&transform objCType:@encode(CGAffineTransform)] forKeyPath:@"inputTransform"];
        CIImage *clampedImage = [clampFilter outputImage];
        
        CIFilter *blurFilter = [CIFilter filterWithName:@"CIGaussianBlur"];
        [blurFilter setDefaults];
        [blurFilter setValue:clampedImage forKey:@"inputImage"];
        [blurFilter setValue:@(50.0f) forKey:@"inputRadius"];    // set value for blur level
        CIImage *outputImage = [blurFilter outputImage];
        
        CIContext *context = [CIContext contextWithOptions:nil];
        CGImageRef inputCGImage = [context createCGImage:outputImage fromRect:inputCIImage.extent];
        GPUImagePicture * blurGPUImage = [[GPUImagePicture alloc] initWithCGImage:inputCGImage];
        CGImageRelease(inputCGImage);
        
        GPUImagePicture *inputGPUImage = [[GPUImagePicture alloc] initWithImage:inputImage];
        
        GPUImageDivideBlendFilter *divideBlendFilter = [[GPUImageDivideBlendFilter alloc] init];
        [inputGPUImage addTarget:divideBlendFilter atTextureLocation:0];
        [blurGPUImage addTarget:divideBlendFilter atTextureLocation:1];
        
        [divideBlendFilter useNextFrameForImageCapture];
        [inputGPUImage processImage];
        [blurGPUImage processImage];
        
        
        UIImage *finalImage = [divideBlendFilter imageFromCurrentFramebuffer];
        GPUImagePicture *finalGPUImage = [[GPUImagePicture alloc] initWithImage:finalImage];
        GPUImageContrastFilter *contrastFilter = [[GPUImageContrastFilter alloc] init];
        [finalGPUImage addTarget:contrastFilter];
        [contrastFilter useNextFrameForImageCapture];
        [finalGPUImage processImage];
        
        return [contrastFilter imageFromCurrentFramebuffer];
    }
}

- (NSString *)UMengAnalyticsTitle
{
    return @"图片编辑";
}

@end
